package com.ajmd.onlineexam.service;

import com.ajmd.onlineexam.entity.*;
import com.ajmd.onlineexam.enumeration.StaticFinalValue;
import com.ajmd.onlineexam.mapper.ImageMapper;
import com.ajmd.onlineexam.mapper.OptionMapper;
import com.ajmd.onlineexam.mapper.QuestionBankMapper;
import com.ajmd.onlineexam.mapper.QuestionMapper;
import com.ajmd.onlineexam.vo.OptionVO;
import com.ajmd.onlineexam.vo.QuestionVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ajmd
 * @since 2023/4/17 15:39
 */
@Service
public class QuestionService {
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private OptionMapper optionMapper;
    @Resource
    private OptionService optionService;
    @Resource
    private ImageMapper imageMapper;


    @Transactional
    public int addOrUpdateQuestion(QuestionVO questionVO){
        QuestionPO questionPO = new QuestionPO();
        BeanUtils.copyProperties(questionVO,questionPO);
        //questionVO无id则为新增
        String questionId = ObjectUtils.isEmpty(questionVO.getId()) ?
                UUID.randomUUID().toString() : questionVO.getId();
        questionPO.setId(questionId);
        List<ImagePO> imagePOList = new ArrayList<>();
        if(questionPO.getHasPic()){
            for(ImagePO imagePO:questionVO.getPicList()){
                imagePO.setId(UUID.randomUUID().toString());
                imagePO.setBelongId(questionId);
                imagePO.setBelongSecondlyId(questionId);
                imagePO.setBelongType(StaticFinalValue.IMAGE_QUESTION);
                imagePOList.add(imagePO);
            }
        }
        //单选、多选、判断
        if(ObjectUtils.isNotEmpty(questionVO.getOptionList())){
            List<OptionPO> optionPOList = new ArrayList<>();
            for(OptionVO optionVO:questionVO.getOptionList()){
                OptionPO optionPO = new OptionPO();
                BeanUtils.copyProperties(optionVO,optionPO);
                optionPO.setId(UUID.randomUUID().toString());
                optionPO.setBelongQuestionId(questionId);
                optionPOList.add(optionPO);
                if(optionPO.getHasPic()){
                    for(ImagePO imagePO:optionVO.getPicList()){
                        imagePO.setId(UUID.randomUUID().toString());
                        imagePO.setBelongId(questionId);
                        imagePO.setBelongSecondlyId(optionPO.getId());
                        imagePO.setBelongType(StaticFinalValue.IMAGE_OPTION);
                        imagePOList.add(imagePO);
                    }
                }
            }
            //如果是编辑，提前删除option
            if(ObjectUtils.isNotEmpty(questionVO.getId())){
                LambdaQueryWrapper<OptionPO> optionPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
                optionPOLambdaQueryWrapper.eq(OptionPO::getBelongQuestionId,questionVO.getId());
                optionMapper.delete(optionPOLambdaQueryWrapper);
            }
            //将试题关联的选项内容存入e_option表
            if(ObjectUtils.isNotEmpty(optionPOList)){
                optionMapper.insertBatchSomeColumn(optionPOList);
            }
        }
        //如果是编辑，提前删除图片
        if(ObjectUtils.isNotEmpty(questionVO.getId())){
            LambdaQueryWrapper<ImagePO> imageLambdaQueryWrapper = new LambdaQueryWrapper<>();
            imageLambdaQueryWrapper.like(ImagePO::getBelongId,questionVO.getId());
            imageMapper.delete(imageLambdaQueryWrapper);
        }
        //将试题和选项关联的图片url存入e_image表
        if(ObjectUtils.isNotEmpty(imagePOList)){
            imageMapper.insertBatchSomeColumn(imagePOList);
        }

        if(ObjectUtils.isNotEmpty(questionVO.getId())){ //编辑
            return questionMapper.updateById(questionPO);
        }
        //将试题内容存入e_question表
        return questionMapper.insert(questionPO);
    }

//    @Transactional
//    public int updateQuestion(QuestionVO questionVO){
//        QuestionPO questionPO = new QuestionPO();
//        BeanUtils.copyProperties(questionVO,questionPO);
//    }


    public Page<QuestionPO> getQuestions(String belongQuestionBankId, String account, Integer userType,
                                         Integer currentPage,Integer pageSize, SearchParam searchParam){
        LambdaQueryWrapper<QuestionPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QuestionPO::getBelongQuestionBankId,belongQuestionBankId);
        if(StaticFinalValue.TEACHER.equals(userType)){
            lambdaQueryWrapper.eq(QuestionPO::getCreatePerson,account);
        }
        //搜索条件过滤
        if(ObjectUtils.isNotEmpty(searchParam)){
            if (ObjectUtils.isNotEmpty(searchParam.getSearchValue())){
                lambdaQueryWrapper.like(QuestionPO::getContent,searchParam.getSearchValue());
            }
            //题型过滤
            if(ObjectUtils.isNotEmpty(searchParam.getQuestionType()) && !StaticFinalValue.All_TYPE.equals(searchParam.getQuestionType())){
                lambdaQueryWrapper.eq(QuestionPO::getQuestionType,searchParam.getQuestionType());
            }
            //难度过滤
            if(ObjectUtils.isNotEmpty(searchParam.getDifficulty()) && !StaticFinalValue.ALL_DIFFICULTY.equals(searchParam.getDifficulty())){
                lambdaQueryWrapper.eq(QuestionPO::getDifficulty,searchParam.getDifficulty());
            }
            //评分方式过滤
            if(ObjectUtils.isNotEmpty(searchParam.getGradeMethod()) && !StaticFinalValue.ALL_METHOD.equals(searchParam.getGradeMethod())){
                lambdaQueryWrapper.eq(QuestionPO::getGradeMethod,searchParam.getGradeMethod());
            }
        }
        lambdaQueryWrapper.orderByDesc(QuestionPO::getCreateTime);
        Page<QuestionPO> page = new Page<>(currentPage,pageSize);
        return questionMapper.selectPage(page, lambdaQueryWrapper);
    }


    public QuestionVO getQuestion(String questionId){
        //查询所有选项
        LambdaQueryWrapper<OptionPO> optionQueryWrapper = new LambdaQueryWrapper<>();
        optionQueryWrapper.eq(OptionPO::getBelongQuestionId,questionId)
                .orderByAsc(OptionPO::getOptionChar);
        List<OptionPO> optionPOList = optionMapper.selectList(optionQueryWrapper);
        List<String> imageBelongIds = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(optionPOList)){
            //从选项中提出选项id，用于图片查询
            List<String> ids = optionPOList.stream().map(OptionPO::getId).collect(Collectors.toList());
            imageBelongIds.addAll(ids);
        }
        imageBelongIds.add(questionId);//试题id也加入图像查询
        //查询出相关的图像List
        LambdaQueryWrapper<ImagePO> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.in(ImagePO::getBelongSecondlyId,imageBelongIds);
        List<ImagePO> imagePOList = imageMapper.selectList(imageQueryWrapper);
        //将图像分组存放，以便分别放入optionVO中
        Map<String, List<ImagePO>> imageMap = imagePOList.stream().collect(Collectors.groupingBy(ImagePO::getBelongSecondlyId));
        List<OptionVO> optionVOList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(optionPOList)){
            for(OptionPO optionPO:optionPOList){
                OptionVO optionVO = new OptionVO();
                BeanUtils.copyProperties(optionPO,optionVO);
                optionVO.setPicList(imageMap.get(optionPO.getId()));
                optionVOList.add(optionVO);
            }
        }
        QuestionPO questionPO = questionMapper.selectById(questionId);
        QuestionVO questionVO = new QuestionVO();
        BeanUtils.copyProperties(questionPO,questionVO);
        questionVO.setOptionList(optionVOList);
        questionVO.setPicList(imageMap.get(questionId));
        return questionVO;
    }


    public List<QuestionPO> getQuestionPOs(List<String> questionIds){
        return questionMapper.selectBatchIds(questionIds);
    }

    public List<QuestionVO> getQuestionByIds(List<String> questionIds){
        //查询所有试题
        List<QuestionPO> questionPOList = questionMapper.selectBatchIds(questionIds);
        if(ObjectUtils.isEmpty(questionPOList)){
            return null;
        }
        //试题按照id转为map
        Map<String,QuestionPO> questionPOMap = questionPOList.stream()
                .collect(Collectors.toMap(QuestionPO::getId, Function.identity()));
        //查询所有选项
        LambdaQueryWrapper<OptionPO> optionQueryWrapper = new LambdaQueryWrapper<>();
        optionQueryWrapper.in(OptionPO::getBelongQuestionId,questionIds)
                .orderByAsc(OptionPO::getOptionChar);
        List<OptionPO> optionPOList = optionMapper.selectList(optionQueryWrapper);
        List<String> imageBelongIds = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(optionPOList)){
            //从选项中提出选项id，用于图片查询
            List<String> ids = optionPOList.stream().map(OptionPO::getId).collect(Collectors.toList());
            imageBelongIds.addAll(ids);
        }
        imageBelongIds.addAll(questionIds);//试题id也加入图像查询
        //查询出相关的图像List
        LambdaQueryWrapper<ImagePO> imageQueryWrapper = new LambdaQueryWrapper<>();
        imageQueryWrapper.in(ImagePO::getBelongSecondlyId,imageBelongIds);
        List<ImagePO> imagePOList = imageMapper.selectList(imageQueryWrapper);
        Map<String, List<ImagePO>> imageMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(imagePOList)){
            //将图像按照归属对象分组存放，以便分别放入optionVO中
            imageMap = imagePOList.stream().collect(Collectors.groupingBy(ImagePO::getBelongSecondlyId));
        }

        //将optionPOList转为VOList,并封装进图片
        List<OptionVO> optionVOList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(optionPOList)){
            for(OptionPO optionPO:optionPOList){
                OptionVO optionVO = new OptionVO();
                BeanUtils.copyProperties(optionPO,optionVO);
                optionVO.setPicList(imageMap.get(optionPO.getId()));
                optionVOList.add(optionVO);
            }
        }
        Map<String, List<OptionVO>> optionVOMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(optionVOList)){
            //optionVOList按照所属试题questionId分组存放
            optionVOMap = optionVOList.stream().collect(Collectors.groupingBy(OptionVO::getBelongQuestionId));
        }

        List<QuestionVO> questionVOs = new ArrayList<>();
        //遍历试题id进行封装，将questionPO转为VO,并封装进图片和选项
        for(String questionId:questionIds){
            QuestionPO questionPO = questionPOMap.get(questionId);
            if(ObjectUtils.isEmpty(questionPO)){
                questionVOs.add(null);
                continue;
            }
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(questionPO,questionVO);
            questionVO.setOptionList(optionVOMap.get(questionId));
            questionVO.setPicList(imageMap.get(questionId));
            questionVOs.add(questionVO);
        }
        return questionVOs;
    }




    @Transactional
    /**
     * 根据题库试题 ids,删除试卷试题及关联的选项、图片
     * @param questionIds
     * @return
     */
    public int deleteBankQuestions(List<String> questionIds){
        //删除试题下的选项和图片
        optionService.deleteOptionAndImg(questionIds);
        //删除试题
        return questionMapper.deleteBatchIds(questionIds);

    }


    public int batchUpdateDifficulty(List<String> questionIds,Integer difficulty){
        LambdaUpdateWrapper<QuestionPO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(QuestionPO::getDifficulty,difficulty)
                .in(QuestionPO::getId,questionIds);
        return questionMapper.update(null,lambdaUpdateWrapper);
    }
}
